library Follower requires Unit

struct Follower extends array
    unit m_leader
    unit m_follower

    private timer m_timer

    static method get takes unit u returns thistype
        local thistype this = thistype(Unit.get(u))
            
        if this.m_follower == null then
            set this.m_follower = u
        endif

        return this
    endmethod

    private method getDataTimer takes nothing returns timer
        if this.m_timer == null then
            set this.m_timer = NewTimer()
            call SetTimerData(this.m_timer, this)
        endif
        return this.m_timer
    endmethod

    method destroy takes nothing returns nothing
        if m_timer != null then
            call ReleaseTimer(m_timer)
        endif

        set m_timer = null
        set m_leader = null
        set m_follower = null
    endmethod

    private method doMove takes nothing returns nothing
        local integer r
        local real x
        local real y
        local real distance

        if m_leader == null then
            return
        endif

        set r = GetRandomInt(0, 100)
        set x = GetUnitX(.m_leader) + 100.00 * Cos((GetUnitFacing(.m_leader) + 180.00) * bj_DEGTORAD)
        set y = GetUnitY(.m_leader) + 100.00 * Sin((GetUnitFacing(.m_leader) + 180.00) * bj_DEGTORAD)
        set distance = GetDistanceByXY(GetUnitX(.m_leader),GetUnitY(.m_leader),GetUnitX(.m_follower),GetUnitY(.m_follower))

        if distance > 600.00 and distance <= 1200.00 then
            call IssuePointOrderById(.m_follower, ORDER_UTARG_ATTACK, x, y)
        elseif distance > 1200.00 then
            call IssueTargetOrderById(.m_follower, ORDER_PTARG_PATROL, .m_leader)
        endif
    endmethod

    private method doAttack takes nothing returns nothing

    endmethod

    private static method anon1 takes nothing returns nothing
        local thistype this = GetTimerData(GetExpiredTimer())

        if IsUnitAlive(this.m_follower) and IsUnitAlive(this.m_leader) then
            call this.doMove()
            call this.doAttack()
        else
            call this.destroy()
        endif
    endmethod

    method setLeader takes unit u returns nothing
        set this.m_leader = u

        if m_timer == null then
            //移动
            call TimerStart(this.getDataTimer(), 1.00, true, function thistype.anon1)
        endif
    endmethod

    private static method onUnitDamage takes nothing returns nothing
        //local Unit du = Unit.get(Damage.target)
        //local Unit ds = Unit.get(Damage.source)
        local thistype this = thistype.get(Damage.target)

        if this.m_leader != null then
        endif

    endmethod

    static method init takes nothing returns nothing
        call Damage.register(function thistype.onUnitDamage)
    endmethod

    implement Initialize

endstruct

endlibrary
